#include<config.h>
#include<input_manager.h>
#include<string.h>

static PT_InputOpr g_ptInputOprHead;
static T_InputEvent g_tInputEvent;

static pthread_mutex_t g_tMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t g_tConVar = PTHREAD_COND_INITIALIZER;

//用链表管理输入事件
//  * 函数名称： RegisterInputOpr
//  * 功能描述： 注册"输入模块"
//  * 输入参数： ptInputOpr - 输入模块的结构体指针
//  * 输出参数： 无
//  * 返 回 值： 0 - 成功, 其他值 - 失败
int RegisterInputOpr(PT_InputOpr ptInputOpr)
{
    PT_InputOpr ptTmp;
    if(!g_ptInputOprHead)
    {
        g_ptInputOprHead = ptInputOpr;
        ptInputOpr->ptNext = NULL;
    }
    else{
        //如果链表头不为空，则一直遍历找到尾部
        ptTmp = g_ptInputOprHead;
        while(ptTmp->ptNext)
        {
            ptTmp = ptTmp->ptNext;
        }
        ptTmp->ptNext = ptInputOpr;
        ptInputOpr->ptNext = NULL;
    }
}

void ShowInputOpr(void)
{
   int i = 0;
   PT_InputOpr ptTmp = g_ptInputOprHead;
   while(ptTmp)
   {
        printf("%02d %s\n", i++, ptTmp->name);
        ptTmp = ptTmp->ptNext;
   }
}

//  * 函数名称： InputEventThreadFunction
//  * 功能描述： "输入模块"的线程函数,每个输入模块都是通过创建子线程来读取输入数据,
//  *            读到数据后它会唤醒等得数据的其他线程
//  * 输入参数： pVoid - 输入模块的"读输入数据函数"
//  * 输出参数： 无
//  * 返 回 值： NULL - 正常退出
static void *InputEventThreadFunction(void *pVoid)
{
    T_InputEvent tInputEvent;

    int (*GetInputEvent)(PT_InputEvent ptInputEvent);
    GetInputEvent = (int(*)(PT_InputEvent))pVoid;

    while(1)
    {
        if(0 == GetInputEvent(&tInputEvent))
        {
            pthread_mutex_lock(&g_tMutex);
            g_tInputEvent = tInputEvent;

            //唤醒主线程
            pthread_cond_signal(&g_tConVar);
            //释放互斥量
            pthread_mutex_unlock(&g_tMutex);
        }
    }
    return NULL;
}



//  * 功能描述： 调用所有"输入模块"的设备相关的初始化函数
//  *            并创建用于读取输入数据的子线程
//  * 返 回 值： 0 - 成功, 其他值 - 失败
int AllInputDevicesInit(void)
{
    PT_InputOpr ptTmp = g_ptInputOprHead;
    int iError = -1;
    while(ptTmp)
    {
        if(0 == ptTmp->DeviceInit())
        {
            pthread_create(&ptTmp->tTreadID, NULL, InputEventThreadFunction, ptTmp->GetInputEvent);
            iError = 0;
        }
        ptTmp = ptTmp->ptNext;
    }
    return iError;
}


//  * 函数名称： GetInputEvent
//  * 功能描述： 获得输入数据,它会使得当前线程休眠,
//  *            当各输入模块的子线程读到数据后会把它唤醒
//  * 输入参数： 无
//  * 输出参数： ptInputEvent - 内含得到的输入数据
//  * 返 回 值： 0 - 成功
int GetInputEvent(PT_InputEvent ptInputEvent)
{
    pthread_mutex_lock(&g_tMutex);
    pthread_cond_wait(&g_tConVar, &g_tMutex);

    *ptInputEvent = g_tInputEvent;
    pthread_mutex_unlock(&g_tMutex);
    return 0;
}

//  * 函数名称： InputInit
//  * 功能描述： 调用各个输入模块的初始化函数,就是注册各个输入模块
//  * 输入参数： 无
//  * 输出参数： 无
//  * 返 回 值： 0 - 成功, 其他值 - 失败
int InputInit(void)
{
    int iError;
    iError |= TouchScreenInit();
    return iError;
}